package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.constant.MessageConstant;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.message.pojo.NcMessage;
import com.nineclock.system.dto.SysAllowedJoinCompanyUserDTO;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.easyescel.ExcelMember;
import com.nineclock.system.easyescel.MemberParseListener;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysCompanyUserServiceImpl implements SysCompanyUserService {

    @Autowired
    SysCompanyUserMapper sysCompanyUserMapper;
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    RocketMQTemplate rocketMQ;
    @Autowired
    SysDepartmentMapper departmentMapper;
    @Autowired
    SysCompanyUserRoleMapper companyUserRoleMapper;
    @Autowired
    SysRoleMapper roleMapper;


    @Override
    public SysCompanyUserDTO getCurrentAdmin() {
        //获取企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();
        //通过企业id查询  企业管理员
        SysCompanyUser companyUser = sysCompanyUserMapper.getCompanyUser(companyId);

        return BeanHelper.copyProperties(companyUser, SysCompanyUserDTO.class);

    }

    @Override
    public List<SysCompanyUserDTO> queryCompanyMemberList() {
        //获取企业id'
        Long companyId = CurrentUserHolder.get().getCompanyId();
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        wrapper.eq(SysCompanyUser::getEnable, 1);

        List<SysCompanyUser> sysCompanyUsers = sysCompanyUserMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(sysCompanyUsers)) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        //jopo --> DTO
        List<SysCompanyUserDTO> sysCompanyUserDTOList = BeanHelper.copyWithCollection(sysCompanyUsers, SysCompanyUserDTO.class);

        return sysCompanyUserDTOList;
    }

    @Override
    public void allowedJoinCompany(SysAllowedJoinCompanyUserDTO sysAllowedJoinCompanyUserDTO) {
        //健壮性判断
        if (sysAllowedJoinCompanyUserDTO == null || sysAllowedJoinCompanyUserDTO.getApproved() == null || sysAllowedJoinCompanyUserDTO.getApplyUserId() == null || sysAllowedJoinCompanyUserDTO.getNotifyMsgId() == null || sysAllowedJoinCompanyUserDTO.getRemark() == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //查询 申请人信息
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysCompanyUser::getUserId, sysAllowedJoinCompanyUserDTO.getApplyUserId());
        SysCompanyUser sysCompanyUser = sysCompanyUserMapper.selectOne(wrapper);
        if (sysCompanyUser == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        //通过  或  拒绝
        if (sysAllowedJoinCompanyUserDTO.getApproved()) {
            //通过  更改员工状态
            sysCompanyUser.setRemark(sysAllowedJoinCompanyUserDTO.getRemark());  //批注
            sysCompanyUser.setDepartmentName("同意");     //状态
            SysUser sysUser = sysUserMapper.selectById(sysAllowedJoinCompanyUserDTO.getApplyUserId());
            if (sysUser != null) {
                sysCompanyUser.setUserName(sysUser.getUsername());       //申请人名称
                //更新mongodb
                rocketMQ.convertAndSend("allowedJoinCompanyTopic", sysAllowedJoinCompanyUserDTO.getNotifyMsgId());


                //发送消息到RocketMQ, 推送消息给该用户, 通知审核通过
                NcMessage message = new NcMessage();
                message.setApplyUserId(sysAllowedJoinCompanyUserDTO.getApplyUserId());
                message.setApplyUsername(sysCompanyUser.getUserName());
                message.setMessageType(MessageConstant.COMPANY_APPLY_PASS);
                message.setContent(sysCompanyUser.getUserName() + " 加入企业请求,申请通过!");

                message.setApproveUserId(CurrentUserHolder.get().getId());
                message.setApproveUsername(CurrentUserHolder.get().getUsername());
                message.setTargets(Collections.singletonList(sysUser.getMobile()));
                message.setTitle("企业申请信息");

                System.err.println("===============  " + message);
                log.info("发送消息到MQ , 推送审核通过的消息给系统管理员 ");
                rocketMQ.convertAndSend("messagePushTopic", message);
            }
        } else {
            //TODO  企业申请 拒绝未写
            sysCompanyUserMapper.deleteById(sysCompanyUser);
        }
    }

    @Override
    public PageResult<SysCompanyUserDTO> members(Integer page, Integer pageSize, String keyword, Long departmentId) {
        //部门及子部门 的id
        List<Long> list = new ArrayList<>();
        if (departmentId != 0) {
            list.add(departmentId);
        }
        queryDepartmentIds(departmentId, list);


        //分页查询 (先定义mybatis plus拦截器)
        //分页参数
        Page<SysCompanyUser> page1 = new Page<>(page, pageSize);
        //其他参数
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper();
        //关键词
        if (keyword != null) {
            wrapper.and(wrapper1 -> {
                wrapper1.like(SysCompanyUser::getUserName, keyword)
                        .or().like(SysCompanyUser::getMobile, keyword)
                        .or().like(SysCompanyUser::getWorkNumber, keyword);
            });
        }
        //企业id
        wrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        //部门ids
        wrapper.in(SysCompanyUser::getDepartmentId, list);
        sysCompanyUserMapper.selectPage(page1, wrapper);


        //封装pageResult
        List<SysCompanyUser> records = page1.getRecords();
        if (records != null) {
            List<SysCompanyUserDTO> sysCompanyUserDTOList = BeanHelper.copyWithCollection(records, SysCompanyUserDTO.class);
            PageResult<SysCompanyUserDTO> pageResult = new PageResult<>();
            pageResult.setRows(sysCompanyUserDTOList);
            pageResult.setTotal(page1.getTotal());
            pageResult.setTotalPage(page1.getPages());
            return pageResult;
        }
        return new PageResult<>();

    }

    @Override
    public void uploadExcel(MultipartFile excelFile) throws IOException {
        //读取文件
        EasyExcel.read(excelFile.getInputStream(), ExcelMember.class, new MemberParseListener(this))
                .sheet(0)
                .doRead();

    }


    public void importData(List<ExcelMember> data) {
        //健壮性判断
        if (data != null) {
            for (ExcelMember excelMember : data) {
                LambdaQueryWrapper<SysUser> userQW = new LambdaQueryWrapper<>();

                userQW.eq(SysUser::getEmail, excelMember.getEmail())
                        .or()
                        .eq(SysUser::getMobile, excelMember.getMobile());
                //手机号||邮箱  ------查---->  用户表
                Integer integer = sysUserMapper.selectCount(userQW);
                if (integer > 0) {
                    throw new NcException(ResponseEnum.USER_MOBILE_EMAIL_EXISTS);
                }
                //工号  ------查------>  员工表
                LambdaQueryWrapper<SysCompanyUser> companyUserQW = new LambdaQueryWrapper<>();
                companyUserQW.eq(SysCompanyUser::getWorkNumber, excelMember.getWorkNumber());
                companyUserQW.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
                Integer integer1 = sysCompanyUserMapper.selectCount(companyUserQW);
                if (integer1 > 0) {
                    throw new NcException(ResponseEnum.WROK_NUM_EXISTS);
                }

                //新增用户
                SysUser user = new SysUser();
                user.setUsername(excelMember.getName());
                user.setPassword(new BCryptPasswordEncoder().encode("123456")); //初始密码
                user.setMobile(excelMember.getMobile());
                user.setEmail(excelMember.getEmail());
                user.setStatus((short) 1);
                user.setCreateTime(new Date());
                user.setLastLoginCompanyId(CurrentUserHolder.get().getCompanyId());
                sysUserMapper.insert(user);

                //新增角色
                SysCompanyUser companyUser = new SysCompanyUser();
                companyUser.setUserId(user.getId());
                companyUser.setCompanyId(CurrentUserHolder.get().getCompanyId());
                companyUser.setCompanyName(CurrentUserHolder.get().getCompanyName());
                companyUser.setPost(excelMember.getPosition());
                companyUser.setWorkNumber(excelMember.getWorkNumber());
                companyUser.setEmail(excelMember.getEmail());
                companyUser.setOfficeAddress(excelMember.getWorkAddr());
                companyUser.setEnable((short) 1);
                companyUser.setTimeEntry(excelMember.getEntryTime());
                companyUser.setCreateTime(new Date());
                companyUser.setMobile(excelMember.getMobile());
                companyUser.setUserName(excelMember.getName());

                LambdaQueryWrapper<SysDepartment> departmentQW = new LambdaQueryWrapper<>();
                departmentQW.eq(SysDepartment::getName,excelMember.getPosition());
                departmentQW.eq(SysDepartment::getCompanyId,CurrentUserHolder.get().getCompanyId());
                SysDepartment department = departmentMapper.selectOne(departmentQW);
                if (department != null) {
                    companyUser.setDepartmentId(department.getId()); //部门id 名称
                    companyUser.setDepartmentName(department.getName());
                }
                sysCompanyUserMapper.insert(companyUser);

                //维护员工个 角色
                LambdaQueryWrapper<SysRole> roleQW = new LambdaQueryWrapper<>();
                roleQW.eq(SysRole::getRoleName,excelMember.getPosition());
                roleQW.eq(SysRole::getCompanyId,CurrentUserHolder.get().getCompanyId());
                SysRole role = roleMapper.selectOne(roleQW);
                if (role != null){
                    SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
                    companyUserRole.setRoleId(role.getId());
                    companyUserRole.setCompanyUserId(companyUser.getId());
                    companyUserRole.setCompanyId(CurrentUserHolder.get().getCompanyId());
                    companyUserRoleMapper.insert(companyUserRole);
                }


            }

        }


        //用户表
        //员工表
    }

    @Override
    public Integer queryUserCountByDepartmentIds(List<Long> departmentIds) {
        //健壮性判断
        if (CollectionUtil.isEmpty(departmentIds)){
            return 0;
        }

        List<Long> ids = new ArrayList<>();
        ids.addAll(departmentIds);

        for (Long departmentId : departmentIds) {
            //递归查所有子部门
            this.queryDepartmentIds(departmentId, ids);
        }
        LambdaQueryWrapper<SysCompanyUser> companyUserQW = new LambdaQueryWrapper<>();
        companyUserQW.in(SysCompanyUser::getDepartmentId,ids);
        companyUserQW.eq(SysCompanyUser::getCompanyId,CurrentUserHolder.get().getCompanyId());
        //查所有的员工数
        Integer integer = sysCompanyUserMapper.selectCount(companyUserQW);
        return integer;
    }


    //查子部门
    public void queryDepartmentIds(Long departmentId, List<Long> list) {
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysDepartment::getParentId, departmentId);
        //子部门列表
        List<SysDepartment> departments = departmentMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(departments)) {
            //抽取部门id
            //map: 映射
            //collect: 指定的要转换的集合类型
            List<Long> ids = departments.stream().map(departmen -> {
                return departmen.getId();
            }).collect(Collectors.toList());
            list.addAll(ids);
            for (Long id : ids) {
                this.queryDepartmentIds(id, list);
            }
        }
    }
}
